home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume11 / ephem4.12 / part01 next >
Encoding:
Text File  |  1990-03-12  |  48.9 KB  |  1,701 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v11i027: repost of ephem, v4.12, file 1
  3. From: ecd@cs.umn.edu@ncs-med.UUCP (Elwood C. Downey)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 11, Issue 27
  7. Submitted-by: ecd@cs.umn.edu@ncs-med.UUCP (Elwood C. Downey)
  8. Archive-name: ephem4.12/part01-repost
  9.  
  10. [I tested it here on uunet; it unshars fine.
  11.  
  12. Between this and the last posting (and the botched unofficial patch posting),
  13. I just grandfathered the old single-post style in my poster.  How do software
  14. houses with *production* programs cope?  ;-)  ++bsa]
  15.  
  16. Several sites are reporting that the first file in my 7-part posting of
  17. ephem was munged. they all reported the same munging, so evidently
  18. it got posted badly. Here it is again; could you please repost it asap?
  19.  
  20. --------------------------------------------------------------------------
  21. # This is the first line of a "shell archive" file.
  22. # This means it contains several files that can be extracted into
  23. # the current directory when run with the sh shell, as follows:
  24. #    sh < this_file_name
  25. # This is file 1.
  26. echo x Manifest
  27. sed -e 's/^X//' << 'EOFxEOF' > Manifest
  28. XFiles shipped as the ephem v4.12 package:
  29. X
  30. XMakefile    just say "make"
  31. XMan.txt        manual, ready for a very generic printer.
  32. XManifest    this file.
  33. XReadme        check here for hints before building.
  34. Xephem.cfg    sample configuration file. you'll want to edit this for your
  35. X        particular location and interests after reading the manual.
  36. X
  37. XThe source files:
  38. Xaa_hadec.c    convert between alt/az and hour angle/dec.
  39. Xaltmenus.c    draws the three alternate lower screens.
  40. Xanomaly.c    compute anomaly.
  41. Xastro.h        unit conversion macros and planet defines.
  42. Xcal_mjd.c    converters to and from modified julian date.
  43. Xcircum.c    main "astronomy" entry point that finds where anything is.
  44. Xcircum.h    defines Now and Sky structures.
  45. Xcomet.c        compute comet position from elements.
  46. Xcompiler.c    compile and execute general expressions with screen fields.
  47. Xeq_ecl.c    convert between equitorial and eclipitic coords.
  48. Xflog.c        logs and retrieves screen locations for logging purposes.
  49. Xformats.c    basic date, time, prompts, etc formats.
  50. Xio.c        basic cursor and screen io control.
  51. Xmain.c        main loop.
  52. Xmainmenu.c    draws the top screen.
  53. Xmoon.c        compute moon position.
  54. Xmoonnf.c    compute new and full moon dates.
  55. Xnutation.c    compute nutation correction.
  56. Xobjx.c        set and make use of all the object-x info.
  57. Xobliq.c        compute obliquity.
  58. Xparallax.c    functions to compute earth rim parallax correction.
  59. Xpelement.c    basic planet position polynomial coefficients.
  60. Xplans.c        use polynomials to find planet location at any certain time.
  61. Xplot.c        set fields for and manage plots.
  62. Xpopup.c        handle the one-liner "popup" menus at the top of the screen.
  63. Xprecess.c    compute precession correction.
  64. Xreduce.c    convert elliptical elements from one epoch to another.
  65. Xrefract.c    atmospheric refraction model.
  66. Xriset.c        find basic rise/set sideral times of a fixed object.
  67. Xriset_c.c    iteratively solve for local rise/set times of moving objects.
  68. Xscreen.h    define all field locations and codes, extra planet codes.
  69. Xsel_fld.c    handle cursor movement commands in the various screens.
  70. Xsex_dec.c    convert between sexagesimal and decimal notation.
  71. Xsrch.c        set and manage the various search functions.
  72. Xsun.c        compute location of sun at any time.
  73. Xtime.c        manage setting and getting the time from the os.
  74. Xutc_gst.c    convert between UT1 and Greenwich sidereal time.
  75. Xversion.c    current version notice, and revision history comments.
  76. Xwatch.c        manage the screen during sky and solar system displays.
  77. EOFxEOF
  78. len=`wc -c < Manifest`
  79. if expr $len != 2381 > /dev/null
  80. then echo Length of Manifest is $len but it should be 2381.
  81. fi
  82. echo x Readme
  83. sed -e 's/^X//' << 'EOFxEOF' > Readme
  84. XGeneral Notes for version 4.12:
  85. X
  86. X1) Read the generic-printer-ready manual in Man.txt.
  87. X
  88. X2) Ephem does not gracefully handle the fact that there is no year 0 in the
  89. X   Christian calendar. It is best to avoid entering a year of 0 for now.
  90. X
  91. XChange Highlights:
  92. X
  93. X1) changes from 4.10 to 4.12:
  94. X    major change is support for optional object to be specified as either a
  95. X    fixed object, or via heliocentric elliptical or parabolic orbital
  96. X    elements. a simple logarithmic magnitude model is also supported.
  97. X    fix slight bug related to nutation.
  98. X    plot fields in the same order they were selected.
  99. X    add copywrite notice in main.c.
  100. X    note <sys/time.h> in time.c for BSD 4.3.
  101. X    add confirmation question before quitting.
  102. X    add d,o,z special speed move chars.
  103. X    watch: add LST to night sky and maintain RTC time back in main.
  104. X    fix bug in timezone related to daytime flag.
  105. X    add w (week) watch advance key code.
  106. X    allow for precession moving dec outside range -90..90.
  107. X    fix bug that wiggled cursor during plotting in rise/set menu.
  108. X    fix bug preventing DAWN/DUSK/LON from being used in search function.
  109. X    add PC_GRAPHICS option in mainmenu.c (no effect on unix version).
  110. X    fix twilight error when sun never gets as low as -18 degs.
  111. X    always find alt/az from eod ra/dec, not from precessed values.
  112. X    lastmjd in plans.c was an int: prevented needless recalcs.
  113. X
  114. X 2) changes from 4.8 to 4.10:
  115. X    fix transit times of circumpolar objects that don't rise.
  116. X    fix plotting search function when searching is not on.
  117. X    fix Objx rise/set bug.
  118. X    don't erase last watch positions until computed all new ones.
  119. X    added USE_BIOSCALLS to io.c: Doug McDonald's BIOS calls
  120. X    allow dates to be entered as decimal years (for help with plots).
  121. X    remove literal ESC chars in strings in io.c.
  122. X    provide two forms of non-blocking reads for unix in io.c.
  123. X    take out superfluous ESC testing in chk_arrow().
  124. X    guard better against bogus chars in sel_fld().
  125. X    use %lf in scanf's.
  126. X    command-line arg PROPTS+ adds to settings from config file.
  127. X    change (int) casts in moduloes to (long) for 16bit int systems.
  128. X
  129. XIf you have source, here is how you can build ephem:
  130. X
  131. X1) io.c:
  132. X   define either UNIX or TURBO_C in io.c depending on whether you wish to
  133. X   compile under unix or dos/turbo/lattice/microsoft.
  134. X
  135. X   Also in io.c and if you use unix, you have two choices of methods for doing
  136. X   non-blocking reads depending on whether you define USE_NDELAY; use whichever
  137. X   works for you.
  138. X
  139. X   MSDOS users can do cursor control with direct BIOS calls (the default),
  140. X   or with ANSI.SYS by defining USE_ANSISYS in io.c.
  141. X
  142. X2) time.c:
  143. X   Select from two methods of dealing with time from the operating system
  144. X   with the TZA/TZB defines in time.c. If you get link undefines related to
  145. X   time functions try changing to the other form.
  146. X
  147. X   On Sun systems running OS 4.0.3 (or BSD 4.3) or Apollo SR 10.1 use TZB and
  148. X   change <time.h> to <sys/time.h>.
  149. X
  150. X3) mainmenu.c:
  151. X   if you are compiling for an IBM-PC then try #define PC_GRAPHICS for a bit
  152. X   nicer looking way to draw the screen boundry lines.
  153. X
  154. X4) beware that I have not used string.h or strings.h. if your library's
  155. X   strlen() and str.*cmp() functions don't return int (such as long), then you
  156. X   will have to hand add string.h or your own extern declarations. strcmp() is
  157. X   used in io.c; strncmp() in compiler.c and main.c; and strlen() is used in 
  158. X   compiler.c, io.c, main.c, mainmenu.c, popup.c and version.c.
  159. X
  160. X5) Ephem can now be built by simply compiling all the .c files and linking them
  161. X   all together. On Unix systems, you must also link with the termcap library
  162. X   (-ltermcap) and possibly the auxiliary math library (-lm) if your default C
  163. X   library does not include all the required transcendental functions.
  164. X
  165. XThe following files are pretty much just pure transliterations from BASIC
  166. Xinto C from machine-readable copies of the programs in Duffett-Smith's book.
  167. XThey have nothing to do with the rest of ephem so they may be used for
  168. Xcompletely different applications if so desired.
  169. X   aa_hadec.c anomaly.c astro.h cal_mjd.c comet.c eq_ecl.c moon.c moonnf.c
  170. X   nutation.c obliq.c parallax.c pelement.c plans.c precess.c reduce.c
  171. X   refract.c riset.c sex_dec.c sun.c utc_gst.c
  172. EOFxEOF
  173. len=`wc -c < Readme`
  174. if expr $len != 4245 > /dev/null
  175. then echo Length of Readme is $len but it should be 4245.
  176. fi
  177. echo x Makefile
  178. sed -e 's/^X//' << 'EOFxEOF' > Makefile
  179. XEPHEM=  aa_hadec.o \
  180. X    altmenus.o \
  181. X    anomaly.o \
  182. X    cal_mjd.o \
  183. X    circum.o \
  184. X    comet.o \
  185. X    compiler.o \
  186. X    eq_ecl.o \
  187. X    flog.o \
  188. X    formats.o \
  189. X    io.o \
  190. X    main.o \
  191. X    mainmenu.o \
  192. X    moon.o \
  193. X    moonnf.o \
  194. X    nutation.o \
  195. X    objx.o \
  196. X    obliq.o \
  197. X    parallax.o \
  198. X    pelement.o \
  199. X    plans.o \
  200. X    plot.o \
  201. X    popup.o \
  202. X    precess.o \
  203. X    reduce.o \
  204. X    refract.o \
  205. X    riset.o \
  206. X    riset_c.o \
  207. X    sel_fld.o \
  208. X    sex_dec.o \
  209. X    srch.o \
  210. X    sun.o \
  211. X    time.o \
  212. X    utc_gst.o \
  213. X    version.o \
  214. X    watch.o
  215. X
  216. Xephem:    $(EPHEM)
  217. X    cc -o $@ $(EPHEM) -ltermcap -lm
  218. EOFxEOF
  219. len=`wc -c < Makefile`
  220. if expr $len != 484 > /dev/null
  221. then echo Length of Makefile is $len but it should be 484.
  222. fi
  223. echo x ephem.cfg
  224. sed -e 's/^X//' << 'EOFxEOF' > ephem.cfg
  225. XUT=1:45:0
  226. XUD=4/5/1990
  227. XTZNAME=CST
  228. XTZONE=6:0;0
  229. XLONG=93:42:8
  230. XLAT=44:50:37
  231. XHEIGHT=800
  232. XTEMP=40
  233. XPRES=29.5
  234. XSTPSZ=RTC
  235. XPROPTS=TSMevmjsunpx
  236. XEPOCH=Eod
  237. XNSTEP=1
  238. X
  239. X* comet halley. elements from Duffett-Smith book; mag from 12/86 S&T pg 666
  240. XOBJX=e,1986.109,76.0081,170.011,0.9673,162.2384,58.1540,17.9435,3.66,7.05
  241. X
  242. X* orion, roughly
  243. XOBJX=fixed,6:0:0,0:0:0,1950
  244. X
  245. X* comet austin, 1989c1, as per IAU Circular 4941 and magnitude rumors.
  246. XOBJX=parabolic,4/9.847/1990,58.911,61.504,.34963,75.409,1950,3.8,13.7
  247. EOFxEOF
  248. len=`wc -c < ephem.cfg`
  249. if expr $len != 487 > /dev/null
  250. then echo Length of ephem.cfg is $len but it should be 487.
  251. fi
  252. echo x astro.h
  253. sed -e 's/^X//' << 'EOFxEOF' > astro.h
  254. X#ifndef PI
  255. X#define    PI        3.141592653589793
  256. X#endif
  257. X
  258. X/* conversions among hours (of ra), degrees and radians. */
  259. X#define    degrad(x)    ((x)*PI/180.)
  260. X#define    raddeg(x)    ((x)*180./PI)
  261. X#define    hrdeg(x)    ((x)*15.)
  262. X#define    deghr(x)    ((x)/15.)
  263. X#define    hrrad(x)    degrad(hrdeg(x))
  264. X#define    radhr(x)    deghr(raddeg(x))
  265. X
  266. X/* ratio of from synodic (solar) to sidereal (stellar) rate */
  267. X#define    SIDRATE        .9972695677
  268. X
  269. X/* manifest names for planets.
  270. X * N.B. must cooincide with usage in pelement.c and plans.c.
  271. X */
  272. X#define    MERCURY    0
  273. X#define    VENUS    1
  274. X#define    MARS    2
  275. X#define    JUPITER    3
  276. X#define    SATURN    4
  277. X#define    URANUS    5
  278. X#define    NEPTUNE    6
  279. X#define    PLUTO    7
  280. EOFxEOF
  281. len=`wc -c < astro.h`
  282. if expr $len != 620 > /dev/null
  283. then echo Length of astro.h is $len but it should be 620.
  284. fi
  285. echo x circum.h
  286. sed -e 's/^X//' << 'EOFxEOF' > circum.h
  287. X#define    SPD    (24.0*3600.0)    /* seconds per day */
  288. X
  289. X#define    EOD    (-9786)        /* special epoch flag: use epoch of date */
  290. X#define    RTC    (-1324)        /* special tminc flag: use rt clock */
  291. X#define    NOMAG    (-2134)        /* special s_mag flag: means undefined */
  292. X#define    NOHELIO    (-2314)        /* special s_hlong flag: means it and s_hlat are
  293. X                 * undefined
  294. X                 */
  295. X
  296. X#define    STDHZN        0    /* rise/set times based on nominal conditions */
  297. X#define    ADPHZN        1    /* rise/set times based on exact current " */
  298. X#define    TWILIGHT    2    /* rise/set times for sun 18 degs below hor */
  299. X
  300. X/* info about our local observing circumstances */
  301. Xtypedef struct {
  302. X    double n_mjd;    /* modified Julian date, ie, days since
  303. X             * Jan 0.5 1900 (== 12 noon, Dec 30, 1899), utc.
  304. X             * enough precision to get well better than 1 second.
  305. X             */
  306. X    double n_lat;    /* latitude, >0 north, rads */
  307. X    double n_lng;    /* longitude, >0 east, rads */
  308. X    double n_tz;    /* time zone, hrs behind UTC */
  309. X    double n_temp;    /* atmospheric temp, degrees C */
  310. X    double n_pressure; /* atmospheric pressure, mBar */
  311. X    double n_height;    /* height above sea level, earth radii */
  312. X    double n_epoch;    /* desired precession display epoch as an mjd, or EOD */
  313. X    char n_tznm[4];    /* time zone name; 3 chars or less, always 0 at end */
  314. X} Now;
  315. Xextern double    mjd_day(), mjd_hr();
  316. X
  317. X/* info about where and how we see something in the sky */
  318. Xtypedef struct {
  319. X    double s_ra;    /* ra, rads (precessed to n_epoch) */
  320. X    double s_dec;    /* dec, rads (precessed to n_epoch) */
  321. X    double s_az;    /* azimuth, >0 e of n, rads */
  322. X    double s_alt;    /* altitude above topocentric horizon, rads */
  323. X    double s_sdist;    /* dist from object to sun, au */
  324. X    double s_edist;    /* dist from object to earth, au */
  325. X    double s_elong;    /* angular sep between object and sun, >0 if east */
  326. X    double s_hlong;    /* heliocentric longitude, rads */
  327. X    double s_hlat;    /* heliocentric latitude, rads */
  328. X    double s_size;    /* angular size, arc secs */
  329. X    double s_phase;    /* phase, % */
  330. X    double s_mag;    /* visual magnitude */
  331. X} Sky;
  332. X
  333. X/* flags for riset_cir() status */
  334. X#define    RS_NORISE    0x001    /* object does not rise as such today */
  335. X#define    RS_2RISES    0x002    /* object rises more than once today */
  336. X#define    RS_NOSET    0x004    /* object does not set as such today */
  337. X#define    RS_2SETS    0x008    /* object sets more than once today */
  338. X#define    RS_CIRCUMPOLAR    0x010    /* object stays up all day today */
  339. X#define    RS_2TRANS    0x020    /* transits twice in one day */
  340. X#define    RS_NEVERUP    0x040    /* object never rises today */
  341. X#define    RS_NOTRANS    0x080    /* doesn't transit today */
  342. X#define    RS_ERROR    0x100    /* can't figure out times... */
  343. X
  344. X/* shorthands for fields a Now pointer, np */
  345. X#define mjd    np->n_mjd
  346. X#define lat    np->n_lat
  347. X#define lng    np->n_lng
  348. X#define tz    np->n_tz
  349. X#define temp    np->n_temp
  350. X#define pressure np->n_pressure
  351. X#define height    np->n_height
  352. X#define epoch    np->n_epoch
  353. X#define tznm    np->n_tznm
  354. EOFxEOF
  355. len=`wc -c < circum.h`
  356. if expr $len != 2795 > /dev/null
  357. then echo Length of circum.h is $len but it should be 2795.
  358. fi
  359. echo x screen.h
  360. sed -e 's/^X//' << 'EOFxEOF' > screen.h
  361. X/* screen layout details
  362. X *
  363. X * it looks better if the fields are drawn in some nice order so it you
  364. X * rearrange the fields, check the menu printing functions.
  365. X */
  366. X
  367. X/* size of screen */
  368. X#define    NR    24
  369. X#define    NC    80
  370. X
  371. X#define    ASPECT    (4./3.)    /* screen width to height dimensions ratio */
  372. X
  373. X#define    GAP    6    /* gap between field name and value */
  374. X
  375. X#define    COL1        1
  376. X#define    COL2        27
  377. X#define    COL3        44
  378. X#define    COL4        61    /* calendar */
  379. X
  380. X#define    R_PROMPT    1    /* prompt row */
  381. X#define    C_PROMPT    COL1
  382. X
  383. X#define    R_NEWCIR    2
  384. X#define    C_NEWCIR    ((NC-17)/2) /* 17 is length of the message */
  385. X
  386. X#define    R_TOP        3    /* first row of top menu items */
  387. X
  388. X#define    R_TZN    (R_TOP+0)
  389. X#define    C_TZN    COL1
  390. X#define    R_LT    R_TZN
  391. X#define    C_LT    (C_TZN+GAP-2)
  392. X#define    R_LD    R_TZN
  393. X#define    C_LD    (C_TZN+13)
  394. X
  395. X#define    R_UT    (R_TOP+1)
  396. X#define    C_UT    COL1
  397. X#define    C_UTV    (C_UT+GAP-2)
  398. X#define    R_UD    R_UT
  399. X#define    C_UD    (C_UT+13)
  400. X
  401. X#define    R_JD    (R_TOP+2)
  402. X#define    C_JD    COL1
  403. X#define    C_JDV    (C_JD+GAP+3)
  404. X
  405. X#define    R_LST    (R_TOP)
  406. X#define    C_LST    COL2
  407. X#define    C_LSTV    (C_LST+GAP)
  408. X
  409. X#define    R_LAT    (R_TOP+0)
  410. X#define    C_LAT    COL3
  411. X#define    C_LATV    (C_LAT+4)
  412. X
  413. X#define    R_DAWN    (R_TOP+2)
  414. X#define    C_DAWN    COL2
  415. X#define    C_DAWNV    (C_DAWN+GAP+3)
  416. X
  417. X#define    R_STPSZ    (R_TOP+7)
  418. X#define    C_STPSZ    COL2
  419. X#define    C_STPSZV (C_STPSZ+GAP-1)
  420. X
  421. X#define    R_HEIGHT (R_TOP+2)
  422. X#define    C_HEIGHT COL3
  423. X#define    C_HEIGHTV (C_HEIGHT+GAP)
  424. X
  425. X#define    R_PRES    (R_TOP+4)
  426. X#define    C_PRES    COL3
  427. X#define    C_PRESV    (C_PRES+GAP)
  428. X
  429. X#define    R_WATCH    (R_TOP+4)
  430. X#define    C_WATCH    COL1
  431. X
  432. X#define    R_SRCH    (R_TOP+5)
  433. X#define    C_SRCH    COL1
  434. X#define    C_SRCHV    (C_SRCH+16)
  435. X
  436. X#define    R_PLOT    (R_TOP+6)
  437. X#define    C_PLOT    (COL1)
  438. X#define    C_PLOTV (C_PLOT+20)
  439. X
  440. X#define    R_ALTM    (R_TOP+7)
  441. X#define    C_ALTM    COL1
  442. X#define    C_ALTMV    (C_ALTM+10)
  443. X
  444. X#define    R_TZONE    (R_TOP+5)
  445. X#define    C_TZONE    COL3
  446. X#define    C_TZONEV (C_TZONE+GAP-1)
  447. X
  448. X#define    R_LONG    (R_TOP+1)
  449. X#define    C_LONG    COL3
  450. X#define    C_LONGV    (C_LONG+4)
  451. X
  452. X#define    R_DUSK    (R_TOP+3)
  453. X#define    C_DUSK    COL2
  454. X#define    C_DUSKV    (C_DUSK+GAP+3)
  455. X
  456. X#define    R_NSTEP (R_TOP+6)
  457. X#define    C_NSTEP    COL2
  458. X#define    C_NSTEPV (C_NSTEP+GAP)
  459. X
  460. X#define    R_TEMP    (R_TOP+3)
  461. X#define    C_TEMP    COL3
  462. X#define    C_TEMPV    (C_TEMP+GAP)
  463. X
  464. X#define    R_EPOCH        (R_TOP+6)
  465. X#define    C_EPOCH        COL3
  466. X#define    C_EPOCHV    (C_EPOCH+GAP)
  467. X
  468. X#define    R_MNUDEP    (R_TOP+6)
  469. X#define    C_MNUDEP    COL3
  470. X#define    C_MNUDEPV    (C_EPOCH+GAP)
  471. X
  472. X#define    R_LON    (R_TOP+4)
  473. X#define    C_LON    COL2
  474. X#define    C_LONV    (C_LON+GAP+3)
  475. X
  476. X#define    R_CAL    R_TOP
  477. X#define    C_CAL   COL4
  478. X
  479. X/* menu 1 info table */
  480. X#define    R_PLANTAB    (R_TOP+9)
  481. X#define    R_SUN        (R_PLANTAB+2)
  482. X#define    R_MOON        (R_PLANTAB+3)
  483. X#define    R_MERCURY    (R_PLANTAB+4)
  484. X#define    R_VENUS        (R_PLANTAB+5)
  485. X#define    R_MARS        (R_PLANTAB+6)
  486. X#define    R_JUPITER    (R_PLANTAB+7)
  487. X#define    R_SATURN    (R_PLANTAB+8)
  488. X#define    R_URANUS    (R_PLANTAB+9)
  489. X#define    R_NEPTUNE    (R_PLANTAB+10)
  490. X#define    R_PLUTO        (R_PLANTAB+11)
  491. X#define    R_OBJX        (R_PLANTAB+12)
  492. X#define    C_OBJ        1
  493. X#define    C_RA        4
  494. X#define    C_DEC        12
  495. X#define    C_AZ        19
  496. X#define    C_ALT        26
  497. X#define    C_HLONG        33
  498. X#define    C_HLAT        40
  499. X#define    C_EDIST        47
  500. X#define C_SDIST     54
  501. X#define    C_ELONG        61
  502. X#define    C_SIZE        68
  503. X#define    C_MAG        73
  504. X#define    C_PHASE        78
  505. X
  506. X/* menu 2 screen items */
  507. X#define    C_RISETM    10
  508. X#define    C_RISEAZ    18
  509. X#define    C_TRANSTM    31
  510. X#define    C_TRANSALT    39
  511. X#define    C_SETTM        52
  512. X#define    C_SETAZ        60
  513. X#define    C_TUP        72
  514. X
  515. X/* menu 3 items */
  516. X#define    C_SUN        4
  517. X#define    C_MOON        11
  518. X#define    C_MERCURY    18
  519. X#define    C_VENUS        25
  520. X#define    C_MARS        32
  521. X#define    C_JUPITER    39
  522. X#define    C_SATURN    46
  523. X#define    C_URANUS    53
  524. X#define    C_NEPTUNE    60
  525. X#define    C_PLUTO        67
  526. X#define    C_OBJX        74
  527. X
  528. X#define    PW    (NC-C_PROMPT+1)    /* total prompt line width */
  529. X
  530. X/* macros to pack a row/col and menu selection flags all into an int.
  531. X * (use this rather than a structure because we can compare them so easily.
  532. X * could use bit fields and a union, but then can't init them or use switch.)
  533. X * bit field defs: [15..14]=menu  [13..12]=flags  [11..7]=row  [6..0]=column.
  534. X * see sel_fld.c.
  535. X * F_MNUX also used in main to manage which bottom menu is up.
  536. X */
  537. X#define    F_CHG        (1<<12)    /* field may be picked for changing */
  538. X#define    F_PLT        (1<<13)    /* field may be picked for plotting */
  539. X#define    F_MMNU        (0<<14)    /* field is on main menu */
  540. X#define    F_MNU1        (1<<14)    /* field is on menu 1 */
  541. X#define    F_MNU2         (2<<14)    /* field is on menu 2 */
  542. X#define    F_MNU3        (3<<14)    /* field is on menu 3 */
  543. X#define    rcfpack(r,c,f)    ((f) | ((r) << 7) | (c))
  544. X#define    unpackr(p)    (((p) >> 7) & 0x1f)
  545. X#define    unpackc(p)    ((p) & 0x7f)
  546. X#define    unpackrc(p)    ((p) & 0xfff)
  547. X#define    tstpackf(p,f)    (((p) & ((f)&0x3000)) && \
  548. X            (((p)&0xc000) == ((f)&0xc000) || ((p)&0xc000) == 0))
  549. X
  550. X/* additions to the planet defines from astro.h.
  551. X * must not conflict, and must fit in range 0..15.
  552. X */
  553. X#define    SUN    (PLUTO+1)
  554. X#define    MOON    (PLUTO+2)
  555. X#define    OBJX    (PLUTO+3)    /* the user-defined object */
  556. X#define    NOBJ    (OBJX+1)    /* total number of objects */
  557. X
  558. X#define    cntrl(x)    ((x) & 037)
  559. X#define    QUIT        cntrl('d')    /* char to exit program */
  560. X#define    HELP        '?'        /* char to give help message */
  561. X#define    REDRAW        cntrl('l')    /* char to redraw (like vi) */
  562. X#define    VERSION        cntrl('v')    /* char to display version number */
  563. X#define    END        'q'        /* char to quit current mode */
  564. EOFxEOF
  565. len=`wc -c < screen.h`
  566. if expr $len != 4950 > /dev/null
  567. then echo Length of screen.h is $len but it should be 4950.
  568. fi
  569. echo x aa_hadec.c
  570. sed -e 's/^X//' << 'EOFxEOF' > aa_hadec.c
  571. X#include <stdio.h>
  572. X#include <math.h>
  573. X#include "astro.h"
  574. X
  575. X/* given latitude (n+, radians), lat, altitude (up+, radians), alt, and
  576. X * azimuth (angle round to the east from north+, radians),
  577. X * return hour angle (radians), ha, and declination (radians), dec.
  578. X */
  579. Xaa_hadec (lat, alt, az, ha, dec)
  580. Xdouble lat;
  581. Xdouble alt, az;
  582. Xdouble *ha, *dec;
  583. X{
  584. X    aaha_aux (lat, az, alt, ha, dec);
  585. X}
  586. X
  587. X/* given latitude (n+, radians), lat, hour angle (radians), ha, and declination
  588. X * (radians), dec,
  589. X * return altitude (up+, radians), alt, and
  590. X * azimuth (angle round to the east from north+, radians),
  591. X */
  592. Xhadec_aa (lat, ha, dec, alt, az)
  593. Xdouble lat;
  594. Xdouble ha, dec;
  595. Xdouble *alt, *az;
  596. X{
  597. X    aaha_aux (lat, ha, dec, az, alt);
  598. X}
  599. X
  600. X/* the actual formula is the same for both transformation directions so
  601. X * do it here once for each way.
  602. X * N.B. all arguments are in radians.
  603. X */
  604. Xstatic
  605. Xaaha_aux (lat, x, y, p, q)
  606. Xdouble lat;
  607. Xdouble x, y;
  608. Xdouble *p, *q;
  609. X{
  610. X    static double lastlat = -1000.;
  611. X    static double sinlastlat, coslastlat;
  612. X    double sy, cy;
  613. X    double sx, cx;
  614. X    double sq, cq;
  615. X    double a;
  616. X    double cp;
  617. X
  618. X    /* latitude doesn't change much, so try to reuse the sin and cos evals.
  619. X     */
  620. X    if (lat != lastlat) {
  621. X        sinlastlat = sin (lat);
  622. X        coslastlat = cos (lat);
  623. X        lastlat = lat;
  624. X    }
  625. X
  626. X    sy = sin (y);
  627. X    cy = cos (y);
  628. X    sx = sin (x);
  629. X    cx = cos (x);
  630. X
  631. X/* define GOODATAN2 if atan2 returns full range -PI through +PI.
  632. X */
  633. X#ifdef GOODATAN2
  634. X    *q = asin ((sy*sinlastlat) + (cy*coslastlat*cx));
  635. X    *p = atan2 (-cy*sx, -cy*cx*sinlastlat + sy*coslastlat);
  636. X#else
  637. X#define    EPS    (1e-20)
  638. X    sq = (sy*sinlastlat) + (cy*coslastlat*cx);
  639. X    *q = asin (sq);
  640. X    cq = cos (*q);
  641. X    a = coslastlat*cq;
  642. X    if (a > -EPS && a < EPS)
  643. X        a = a < 0 ? -EPS : EPS; /* avoid / 0 */
  644. X    cp = (sy - (sinlastlat*sq))/a;
  645. X    if (cp >= 1.0)    /* the /a can be slightly > 1 */
  646. X        *p = 0.0;
  647. X    else if (cp <= -1.0)
  648. X        *p = PI;
  649. X    else
  650. X        *p = acos ((sy - (sinlastlat*sq))/a);
  651. X    if (sx>0) *p = 2.0*PI - *p;
  652. X#endif
  653. X}
  654. EOFxEOF
  655. len=`wc -c < aa_hadec.c`
  656. if expr $len != 1922 > /dev/null
  657. then echo Length of aa_hadec.c is $len but it should be 1922.
  658. fi
  659. echo x altmenus.c
  660. sed -e 's/^X//' << 'EOFxEOF' > altmenus.c
  661. X/* printing routines for the three alternative bottom half menus,
  662. X * "menu1", "menu2" and "menu3".
  663. X */
  664. X
  665. X#include <stdio.h>
  666. X#include <math.h>
  667. X#include "astro.h"
  668. X#include "circum.h"
  669. X#include "screen.h"
  670. X
  671. Xstatic int altmenu = F_MNU1;    /* which alternate menu is up; one of F_MNUi */
  672. Xstatic int alt2_stdhzn;    /* whether to use STDHZN (aot ADPHZN) horizon algthm  */
  673. Xstatic int alt3_geoc;    /* whether to use geocentric (aot topocentric) vantage*/
  674. X
  675. X/* table of screen rows given a body #define from astro/h or screen.h */
  676. Xstatic short bodyrow[NOBJ] = {
  677. X    R_MERCURY, R_VENUS, R_MARS, R_JUPITER, R_SATURN,
  678. X    R_URANUS, R_NEPTUNE, R_PLUTO, R_SUN, R_MOON, R_OBJX
  679. X};
  680. X/* table of screen cols for third menu format, given body #define ... */
  681. Xstatic short bodycol[NOBJ] = {
  682. X    C_MERCURY, C_VENUS, C_MARS, C_JUPITER, C_SATURN,
  683. X    C_URANUS, C_NEPTUNE, C_PLUTO, C_SUN, C_MOON, C_OBJX
  684. X};
  685. X
  686. X/* let op decide which alternate menu should be up,
  687. X * including any menu-specific setup they might require.
  688. X * return 0 if things changed to require updating the alt menu; else -1.
  689. X */
  690. Xaltmenu_setup()
  691. X{
  692. X    static char *flds[5] = {
  693. X        "Data menu", "Rise/Set menu", "Separations menu"
  694. X    };
  695. X    int newmenu = altmenu, newhzn = alt2_stdhzn, newgeoc = alt3_geoc;
  696. X    int new;
  697. X    int fn = altmenu == F_MNU1 ? 0 : altmenu == F_MNU2 ? 1 : 2;
  698. X
  699. X    ask:
  700. X    flds[3]= newhzn ? "Standard hzn" : "Adaptive hzn";
  701. X    flds[4]= newgeoc? "Geocentric" : "Topocentric";
  702. X
  703. X    switch (popup (flds, fn, 5)) {
  704. X    case 0: newmenu = F_MNU1; break;
  705. X    case 1: newmenu = F_MNU2; break;
  706. X    case 2: newmenu = F_MNU3; break;
  707. X    case 3: newhzn ^= 1; fn = 3; goto ask;
  708. X    case 4: newgeoc ^= 1; fn = 4; goto ask;
  709. X    default: return (-1);
  710. X    }
  711. X
  712. X    new = 0;
  713. X    if (newmenu != altmenu) {
  714. X        altmenu = newmenu;
  715. X        new++;
  716. X    }
  717. X    if (newhzn != alt2_stdhzn) {
  718. X        alt2_stdhzn = newhzn;
  719. X        if (newmenu == F_MNU2)
  720. X        new++;
  721. X    }
  722. X    if (newgeoc != alt3_geoc) {
  723. X        alt3_geoc = newgeoc;
  724. X        if (newmenu == F_MNU3)
  725. X        new++;
  726. X    }
  727. X    return (new ? 0 : -1);
  728. X}
  729. X
  730. X/* erase the info for the given planet */
  731. Xalt_nobody (p)
  732. Xint p;
  733. X{
  734. X    f_eol (bodyrow[p], C_RA);
  735. X}
  736. X
  737. Xalt_body (b, force, np)
  738. Xint b;        /* which body, ala astro.h and screen.h defines */
  739. Xint force;    /* if !0 then draw for sure, else just if changed since last */
  740. XNow *np;
  741. X{
  742. X    switch (altmenu) {
  743. X    case F_MNU1: alt1_body (b, force, np); break;
  744. X    case F_MNU2: alt2_body (b, force, np); break;
  745. X    case F_MNU3: alt3_body (b, force, np); break;
  746. X    }
  747. X}
  748. X
  749. X/* draw the labels for the current alternate menu format */
  750. Xalt_labels ()
  751. X{
  752. X    switch (altmenu) {
  753. X    case F_MNU1: alt1_labels (); break;
  754. X    case F_MNU2: alt2_labels (); break;
  755. X    case F_MNU3: alt3_labels (); break;
  756. X    }
  757. X}
  758. X
  759. X/* erase the labels for the current alternate menu format */
  760. Xalt_nolabels ()
  761. X{
  762. X    int i;
  763. X
  764. X    f_string (R_ALTM, C_ALTMV, "             ");
  765. X    for (i = R_PLANTAB; i < R_SUN; i++)
  766. X        f_eol (i, C_RA);
  767. X}
  768. X
  769. Xalt_menumask()
  770. X{
  771. X    return (altmenu);
  772. X}
  773. X
  774. X/* handy function to return the next planet in the order in which they are
  775. X * displayed in the lower half of the screen.
  776. X * input is a given planet, return is the next planet.
  777. X * if input is not legal, then first planet is returned; when input is the
  778. X * last planet, then -1 is returned.
  779. X * typical usage is something like:
  780. X *   for (p = nxtbody(-1); p != -1; p = nxtbody(p))
  781. X */
  782. Xnxtbody(c)
  783. Xint c;
  784. X{
  785. X    static short nxtpl[NOBJ] = {
  786. X        VENUS, MARS, JUPITER, SATURN, URANUS,
  787. X        NEPTUNE, PLUTO, OBJX, MOON, MERCURY, -1
  788. X    };
  789. X
  790. X    if (c < MERCURY || c >= NOBJ)
  791. X        return (SUN);
  792. X    else
  793. X        return (nxtpl[c]);
  794. X}
  795. X
  796. Xstatic
  797. Xalt1_labels()
  798. X{
  799. X    f_string (R_ALTM, C_ALTMV, "  Planet Data");
  800. X
  801. X    f_string (R_PLANTAB,    C_RA,    "R.A.");
  802. X    f_string (R_PLANTAB+1,    C_RA,    "Hr:Mn.d");
  803. X    f_string (R_PLANTAB,    C_DEC,    "Dec");
  804. X    f_string (R_PLANTAB+1,    C_DEC,    "Deg:Mn");
  805. X    f_string (R_PLANTAB,    C_AZ,    "Az");
  806. X    f_string (R_PLANTAB+1,    C_AZ,    "Deg E");
  807. X    f_string (R_PLANTAB,    C_ALT,    "Alt");
  808. X    f_string (R_PLANTAB+1,    C_ALT,    "Deg Up");
  809. X    f_string (R_PLANTAB,    C_HLONG,"Helio");
  810. X    f_string (R_PLANTAB+1,    C_HLONG,"Long");
  811. X    f_string (R_PLANTAB,    C_HLAT,    "Helio");
  812. X    f_string (R_PLANTAB+1,    C_HLAT,    "Lat");
  813. X    f_string (R_PLANTAB,    C_EDIST,"Ea Dst");
  814. X    f_string (R_PLANTAB+1,    C_EDIST,"AU(mi)");
  815. X    f_string (R_PLANTAB,    C_SDIST,"Sn Dst");
  816. X    f_string (R_PLANTAB+1,    C_SDIST,"AU");
  817. X    f_string (R_PLANTAB,    C_ELONG,"Elong");
  818. X    f_string (R_PLANTAB+1,    C_ELONG,"Deg E");
  819. X    f_string (R_PLANTAB,    C_SIZE,    "Size");
  820. X    f_string (R_PLANTAB+1,    C_SIZE,    "ArcS");
  821. X    f_string (R_PLANTAB,    C_MAG,    "VMag");
  822. X    f_string (R_PLANTAB,    C_PHASE,"Phs");
  823. X    f_char (R_PLANTAB+1,    C_PHASE,'%');
  824. X}
  825. X
  826. Xstatic
  827. Xalt2_labels()
  828. X{
  829. X    f_string (R_ALTM, C_ALTMV, "Rise/Set Info");
  830. X
  831. X    f_string (R_PLANTAB,    C_RISETM+5,    "Rise");
  832. X    f_string (R_PLANTAB+1,    C_RISETM+1,    "Time");
  833. X    f_string (R_PLANTAB+1,    C_RISEAZ+2,    "Az");
  834. X    f_string (R_PLANTAB,    C_TRANSTM+3,    "Transit");
  835. X    f_string (R_PLANTAB+1,    C_TRANSTM+1,    "Time");
  836. X    f_string (R_PLANTAB+1,    C_TRANSALT+2,    "Alt");
  837. X    f_string (R_PLANTAB,    C_SETTM+5,    "Set");
  838. X    f_string (R_PLANTAB+1,    C_SETTM+1,    "Time");
  839. X    f_string (R_PLANTAB+1,    C_SETAZ+2,    "Az");
  840. X    f_string (R_PLANTAB,    C_TUP,        "Hrs Up");
  841. X}
  842. X
  843. Xstatic
  844. Xalt3_labels()
  845. X{
  846. X    f_string (R_ALTM, C_ALTMV, "  Separations");
  847. X
  848. X    f_string (R_PLANTAB,    C_SUN+2,    "Sun");
  849. X    f_string (R_PLANTAB,    C_MOON+1,    "Moon");
  850. X    f_string (R_PLANTAB,    C_MERCURY+1,    "Merc");
  851. X    f_string (R_PLANTAB,    C_VENUS+1,    "Venus");
  852. X    f_string (R_PLANTAB,    C_MARS+1,    "Mars");
  853. X    f_string (R_PLANTAB,    C_JUPITER+2,    "Jup");
  854. X    f_string (R_PLANTAB,    C_SATURN,    "Saturn");
  855. X    f_string (R_PLANTAB,    C_URANUS,    "Uranus");
  856. X    f_string (R_PLANTAB,    C_NEPTUNE+2,    "Nep");
  857. X    f_string (R_PLANTAB,    C_PLUTO+1,    "Pluto");
  858. X    f_string (R_PLANTAB,    C_OBJX+3,    "X");
  859. X}
  860. X
  861. X/* print body info in first menu format */
  862. Xstatic
  863. Xalt1_body (p, force, np)
  864. Xint p;        /* which body, as in astro.h/screen.h defines */
  865. Xint force;    /* whether to print for sure or only if things have changed */
  866. XNow *np;
  867. X{
  868. X    Sky sky;
  869. X    double as = plot_ison() || srch_ison() ? 0.0 : 60.0;
  870. X    int row = bodyrow[p];
  871. X
  872. X    if (body_cir (p, as, np, &sky) || force) {
  873. X        f_ra (row, C_RA, sky.s_ra);
  874. X        f_angle (row, C_DEC, sky.s_dec);
  875. X        if (p != MOON && sky.s_hlong != NOHELIO) {
  876. X        f_angle (row, C_HLONG, sky.s_hlong);
  877. X        if (p != SUN)
  878. X            f_angle (row, C_HLAT, sky.s_hlat);
  879. X        }
  880. X
  881. X        if (p == MOON) {
  882. X        /* distance is on km, show in miles */
  883. X        f_double (R_MOON, C_EDIST, "%6.0f", sky.s_edist/1.609344);
  884. X        } else if (sky.s_edist > 0.0) {
  885. X        /* show distance in au */
  886. X        f_double (row, C_EDIST,(sky.s_edist>=10.0)?"%6.3f":"%6.4f",
  887. X                                sky.s_edist);
  888. X        }
  889. X        if (sky.s_sdist > 0.0)
  890. X        f_double (row, C_SDIST, (sky.s_sdist>=10.0)?"%6.3f":"%6.4f",
  891. X                                sky.s_sdist);
  892. X        if (p != SUN)
  893. X        f_double (row, C_ELONG, "%6.1f", sky.s_elong);
  894. X        if (p != OBJX)
  895. X        f_double (row, C_SIZE, (p==MOON||p==SUN)?"%4.0f":"%4.1f",
  896. X                                sky.s_size);
  897. X        if (sky.s_mag != NOMAG)
  898. X        f_double (row, C_MAG, (p==MOON||p==SUN)?"%4.0f":"%4.1f",
  899. X                                    sky.s_mag);
  900. X        if (sky.s_sdist > 0.0) {
  901. X        char buf[10];
  902. X        /* some terminals scroll when write a char in low-right corner.
  903. X         * TODO: is there a nicer way to handle this maybe?
  904. X         */
  905. X        int col = row == NR ? C_PHASE - 1 : C_PHASE;
  906. X        /* would just do this if Turbo-C 2.0 "%?.0f" worked:
  907. X         * f_double (row, col, "%3.0f", sky.s_phase);
  908. X         */
  909. X        sprintf (buf, "%3d", (int)(sky.s_phase+0.5));
  910. X        f_string (row, col, buf);
  911. X        }
  912. X    }
  913. X
  914. X    f_angle (row, C_AZ, sky.s_az);
  915. X    f_angle (row, C_ALT, sky.s_alt);
  916. X}
  917. X
  918. X/* print body info in the second menu format */
  919. Xstatic
  920. Xalt2_body (p, force, np)
  921. Xint p;        /* which body, as in astro.h/screen.h defines */
  922. Xint force;    /* whether to print for sure or only if things have changed */
  923. XNow *np;
  924. X{
  925. X    double ltr, lts, ltt, azr, azs, altt;
  926. X    int row = bodyrow[p];
  927. X    int status;
  928. X    double tmp;
  929. X    int today_tup = 0;
  930. X
  931. X    if (!riset_cir (p, np, alt2_stdhzn?STDHZN:ADPHZN, <r, <s, <t,
  932. X                    &azr, &azs, &altt, &status) && !force)
  933. X        return;
  934. X
  935. X    alt_nobody (p);
  936. X
  937. X    if (status & RS_ERROR) {
  938. X        /* can not find where body is! */
  939. X        f_string (row, C_RISETM, "?Error?");
  940. X        return;
  941. X    }
  942. X    if (status & RS_CIRCUMPOLAR) {
  943. X        /* body is up all day */
  944. X        f_string (row, C_RISETM, "Circumpolar");
  945. X        if (status & RS_NOTRANS)
  946. X        f_string (row, C_TRANSTM, "No transit");
  947. X        else {
  948. X        f_mtime (row, C_TRANSTM, ltt);
  949. X        if (status & RS_2TRANS)
  950. X            f_char (row, C_TRANSTM+5, '+');
  951. X        f_angle (row, C_TRANSALT, altt);
  952. X        }
  953. X        f_string (row, C_TUP, "24:00"); /*f_mtime() changes to 0:00 */
  954. X        return;
  955. X    }
  956. X    if (status & RS_NEVERUP) {
  957. X        /* body never up at all today */
  958. X        f_string (row, C_RISETM, "Never up");
  959. X        f_mtime (row, C_TUP, 0.0);
  960. X        return;
  961. X    }
  962. X
  963. X    if (status & RS_NORISE) {
  964. X        /* object does not rise as such today */
  965. X        f_string (row, C_RISETM, "Never rises");
  966. X        ltr = 0.0; /* for TUP */
  967. X        today_tup = 1;
  968. X    } else {
  969. X        f_mtime (row, C_RISETM, ltr);
  970. X        if (status & RS_2RISES) {
  971. X        /* object rises more than once today */
  972. X        f_char (row, C_RISETM+5, '+');
  973. X        }
  974. X        f_angle (row, C_RISEAZ, azr);
  975. X    }
  976. X
  977. X    if (status & RS_NOTRANS)
  978. X        f_string (row, C_TRANSTM, "No transit");
  979. X    else {
  980. X        f_mtime (row, C_TRANSTM, ltt);
  981. X        if (status & RS_2TRANS)
  982. X        f_char (row, C_TRANSTM+5, '+');
  983. X        f_angle (row, C_TRANSALT, altt);
  984. X    }
  985. X
  986. X    if (status & RS_NOSET) {
  987. X        /* object does not set as such today */
  988. X        f_string (row, C_SETTM, "Never sets");
  989. X        lts = 24.0;    /* for TUP */
  990. X        today_tup = 1;
  991. X    } else {
  992. X        f_mtime (row, C_SETTM, lts);
  993. X        if (status & RS_2SETS)
  994. X        f_char (row, C_SETTM+5, '+');
  995. X        f_angle (row, C_SETAZ, azs);
  996. X    }
  997. X
  998. X    tmp = lts - ltr;
  999. X    if (tmp < 0)
  1000. X        tmp = 24.0 + tmp;
  1001. X    f_mtime (row, C_TUP, tmp);
  1002. X    if (today_tup)
  1003. X        f_char (row, C_TUP+5, '+');
  1004. X}
  1005. X
  1006. X/* print body info in third menu format. this may be either the geocentric
  1007. X *   or topocentric angular separation between object p and each of the others.
  1008. X *   the latter, of course, includes effects of refraction and so can change
  1009. X *   quite rapidly near the time of each planets rise or set.
  1010. X * for now, we don't save old values so we always redo everything and ignore
  1011. X *  the "force" argument. this isn't that bad since body_cir() has memory and
  1012. X *   will avoid most computations as we hit them again in the lower triangle.
  1013. X */
  1014. X/*ARGSUSED*/
  1015. Xstatic
  1016. Xalt3_body (p, force, np)
  1017. Xint p;        /* which body, as in astro.h/screen.h defines */
  1018. Xint force;    /* whether to print for sure or only if things have changed */
  1019. XNow *np;
  1020. X{
  1021. X    int row = bodyrow[p];
  1022. X    Sky skyp, skyq;
  1023. X    double spy, cpy, px, *qx, *qy;
  1024. X    int wantx = objx_ison();
  1025. X    double as = plot_ison() || srch_ison() ? 0.0 : 60.0;
  1026. X    int q;
  1027. X
  1028. X    (void) body_cir (p, as, np, &skyp);
  1029. X    if (alt3_geoc) {
  1030. X        /* use ra for "x", dec for "y". */
  1031. X        spy = sin (skyp.s_dec);
  1032. X        cpy = cos (skyp.s_dec);
  1033. X        px = skyp.s_ra;
  1034. X        qx = &skyq.s_ra;
  1035. X        qy = &skyq.s_dec;
  1036. X    } else {
  1037. X        /* use azimuth for "x", altitude for "y". */
  1038. X        spy = sin (skyp.s_alt);
  1039. X        cpy = cos (skyp.s_alt);
  1040. X        px = skyp.s_az;
  1041. X        qx = &skyq.s_az;
  1042. X        qy = &skyq.s_alt;
  1043. X    }
  1044. X    for (q = nxtbody(-1); q != -1; q = nxtbody(q))
  1045. X        if (q != p && (q != OBJX || wantx)) {
  1046. X        double csep;
  1047. X        (void) body_cir (q, as, np, &skyq);
  1048. X        csep = spy*sin(*qy) + cpy*cos(*qy)*cos(px-*qx);
  1049. X        f_angle (row, bodycol[q], acos(csep));
  1050. X        }
  1051. X}
  1052. EOFxEOF
  1053. len=`wc -c < altmenus.c`
  1054. if expr $len != 10912 > /dev/null
  1055. then echo Length of altmenus.c is $len but it should be 10912.
  1056. fi
  1057. echo x anomaly.c
  1058. sed -e 's/^X//' << 'EOFxEOF' > anomaly.c
  1059. X#include <stdio.h>
  1060. X#include <math.h>
  1061. X#include "astro.h"
  1062. X
  1063. X#define    TWOPI    (2*PI)
  1064. X
  1065. X/* given the mean anomaly, ma, and the eccentricity, s, of elliptical motion,
  1066. X * find the true anomaly, *nu, and the eccentric anomaly, *ea.
  1067. X * all angles in radians.
  1068. X */
  1069. Xanomaly (ma, s, nu, ea)
  1070. Xdouble ma, s;
  1071. Xdouble *nu, *ea;
  1072. X{
  1073. X    double m, dla, fea;
  1074. X
  1075. X    m = ma-TWOPI*(long)(ma/TWOPI);
  1076. X    fea = m;
  1077. X    while (1) {
  1078. X        dla = fea-(s*sin(fea))-m;
  1079. X        if (fabs(dla)<1e-6)
  1080. X        break;
  1081. X        dla /= 1-(s*cos(fea));
  1082. X        fea -= dla;
  1083. X    }
  1084. X
  1085. X    *nu = 2*atan(sqrt((1+s)/(1-s))*tan(fea/2));
  1086. X    *ea = fea;
  1087. X}
  1088. EOFxEOF
  1089. len=`wc -c < anomaly.c`
  1090. if expr $len != 557 > /dev/null
  1091. then echo Length of anomaly.c is $len but it should be 557.
  1092. fi
  1093. echo x cal_mjd.c
  1094. sed -e 's/^X//' << 'EOFxEOF' > cal_mjd.c
  1095. X#include <stdio.h>
  1096. X#include <math.h>
  1097. X#include "astro.h"
  1098. X
  1099. X/* given a date in months, mn, days, dy, years, yr,
  1100. X * return the modified Julian date (number of days elapsed since 1900 jan 0.5),
  1101. X * *mjd.
  1102. X */
  1103. Xcal_mjd (mn, dy, yr, mjd)
  1104. Xint mn, yr;
  1105. Xdouble dy;
  1106. Xdouble *mjd;
  1107. X{
  1108. X    int b, d, m, y;
  1109. X    long c;
  1110. X
  1111. X    m = mn;
  1112. X    y = (yr < 0) ? yr + 1 : yr;
  1113. X    if (mn < 3) {
  1114. X        m += 12;
  1115. X        y -= 1;
  1116. X    }
  1117. X
  1118. X    if (yr < 1582 || yr == 1582 && (mn < 10 || mn == 10 && dy < 15)) 
  1119. X        b = 0;
  1120. X    else {
  1121. X        int a;
  1122. X        a = y/100;
  1123. X        b = 2 - a + a/4;
  1124. X    }
  1125. X
  1126. X    if (y < 0)
  1127. X        c = (long)((365.25*y) - 0.75) - 694025L;
  1128. X    else
  1129. X        c = (long)(365.25*y) - 694025L;
  1130. X
  1131. X    d = 30.6001*(m+1);
  1132. X
  1133. X    *mjd = b + c + d + dy - 0.5;
  1134. X}
  1135. X
  1136. X/* given the modified Julian date (number of days elapsed since 1900 jan 0.5,),
  1137. X * mjd, return the calendar date in months, *mn, days, *dy, and years, *yr.
  1138. X */
  1139. Xmjd_cal (mjd, mn, dy, yr)
  1140. Xdouble mjd;
  1141. Xint *mn, *yr;
  1142. Xdouble *dy;
  1143. X{
  1144. X    double d, f;
  1145. X    double i, a, b, ce, g;
  1146. X
  1147. X    d = mjd + 0.5;
  1148. X    i = floor(d);
  1149. X    f = d-i;
  1150. X    if (f == 1) {
  1151. X        f = 0;
  1152. X        i += 1;
  1153. X    }
  1154. X
  1155. X    if (i > -115860.0) {
  1156. X        a = floor((i/36524.25)+.9983573)+14;
  1157. X        i += 1 + a - floor(a/4.0);
  1158. X    }
  1159. X
  1160. X    b = floor((i/365.25)+.802601);
  1161. X    ce = i - floor((365.25*b)+.750001)+416;
  1162. X    g = floor(ce/30.6001);
  1163. X    *mn = g - 1;
  1164. X    *dy = ce - floor(30.6001*g)+f;
  1165. X    *yr = b + 1899;
  1166. X
  1167. X    if (g > 13.5)
  1168. X        *mn = g - 13;
  1169. X    if (*mn < 2.5)
  1170. X        *yr = b + 1900;
  1171. X    if (*yr < 1)
  1172. X        *yr -= 1;
  1173. X}
  1174. X
  1175. X/* given an mjd, set *dow to 0..6 according to which dayof the week it falls
  1176. X * on (0=sunday) or set it to -1 if can't figure it out.
  1177. X */
  1178. Xmjd_dow (mjd, dow)
  1179. Xdouble mjd;
  1180. Xint *dow;
  1181. X{
  1182. X    /* cal_mjd() uses Gregorian dates on or after Oct 15, 1582.
  1183. X     * (Pope Gregory XIII dropped 10 days, Oct 5..14, and improved the leap-
  1184. X     * year algorithm). however, Great Britian and the colonies did not
  1185. X     * adopt it until Sept 14, 1752 (they dropped 11 days, Sept 3-13,
  1186. X     * due to additional accumulated error). leap years before 1752 thus
  1187. X     * can not easily be accounted for from the cal_mjd() number...
  1188. X     */
  1189. X    if (mjd < -53798.5) {
  1190. X        /* pre sept 14, 1752 too hard to correct */
  1191. X        *dow = -1;
  1192. X        return;
  1193. X    }
  1194. X    *dow = ((long)floor(mjd-.5) + 1) % 7;/* 1/1/1900 (mjd 0.5) is a Monday*/
  1195. X    if (*dow < 0)
  1196. X        *dow += 7;
  1197. X}
  1198. X
  1199. X/* given a mjd, return the the number of days in the month.  */
  1200. Xmjd_dpm (mjd, ndays)
  1201. Xdouble mjd;
  1202. Xint *ndays;
  1203. X{
  1204. X    static short dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  1205. X    int m, y;
  1206. X    double d;
  1207. X
  1208. X    mjd_cal (mjd, &m, &d, &y);
  1209. X    *ndays = (m==2 && ((y%4==0 && y%100!=0)||y%400==0)) ? 29 : dpm[m-1];
  1210. X}
  1211. X
  1212. X
  1213. X/* given a mjd, return the year as a double. */
  1214. Xmjd_year (mjd, yr)
  1215. Xdouble mjd;
  1216. Xdouble *yr;
  1217. X{
  1218. X    int m, y;
  1219. X    double d;
  1220. X    double e0, e1;    /* mjd of start of this year, start of next year */
  1221. X
  1222. X    mjd_cal (mjd, &m, &d, &y);
  1223. X    cal_mjd (1, 1.0, y, &e0);
  1224. X    cal_mjd (1, 1.0, y+1, &e1);
  1225. X    *yr = y + (mjd - e0)/(e1 - e0);
  1226. X}
  1227. X
  1228. X/* given a decimal year, return mjd */
  1229. Xyear_mjd (y, mjd)
  1230. Xdouble y;
  1231. Xdouble *mjd;
  1232. X{
  1233. X    double e0, e1;    /* mjd of start of this year, start of next year */
  1234. X    int yf = floor (y);
  1235. X
  1236. X    cal_mjd (1, 1.0, yf, &e0);
  1237. X    cal_mjd (1, 1.0, yf+1, &e1);
  1238. X    *mjd = e0 + (y - yf)*(e1-e0);
  1239. X}
  1240. EOFxEOF
  1241. len=`wc -c < cal_mjd.c`
  1242. if expr $len != 3067 > /dev/null
  1243. then echo Length of cal_mjd.c is $len but it should be 3067.
  1244. fi
  1245. echo x circum.c
  1246. sed -e 's/^X//' << 'EOFxEOF' > circum.c
  1247. X/* fill in a Sky struct with all we know about each object.
  1248. X *(object-x is in objx.c)
  1249. X */
  1250. X
  1251. X#include <stdio.h>
  1252. X#include <math.h>
  1253. X#include "astro.h"
  1254. X#include "circum.h"
  1255. X#include "screen.h"    /* just for SUN and MOON */
  1256. X
  1257. X/* find body p's circumstances now.
  1258. X * to save some time the caller may specify a desired accuracy, in arc seconds.
  1259. X * if, based on its mean motion, it would not have moved this much since the
  1260. X * last time we were called we only recompute altitude and azimuth and avoid
  1261. X * recomputing the planet's heliocentric position. use 0.0 for best possible.
  1262. X * we always recompute objx's position regardless.
  1263. X * return 0 if only alt/az changes, else 1 if all other stuff updated too.
  1264. X * TODO: beware of fast retrograde motions.
  1265. X */
  1266. Xbody_cir (p, as, np, sp)
  1267. Xint p;
  1268. Xdouble as;
  1269. XNow *np;
  1270. XSky *sp;
  1271. X{
  1272. X    typedef struct {
  1273. X        double l_dpas;    /* mean days per arc second */
  1274. X        Now l_now;        /* when l_sky was found */
  1275. X        double l_ra, l_dec;    /* the eod, ie, unprecessed, ra/dec values */
  1276. X        Sky l_sky;
  1277. X    } Last;
  1278. X    /* must be in same order as the astro.h object #define's */
  1279. X    static Last last[8] =
  1280. X        {{.000068},{.00017},{.00053},{.0034},{.0092},{.027},{.046},{.069}};
  1281. X    Last objxlast;
  1282. X    double lst, alt, az;
  1283. X    double ehp, ha, dec;    /* ehp: angular dia of earth from body */
  1284. X    Last *lp;
  1285. X    int new;
  1286. X
  1287. X    switch (p) {
  1288. X    case SUN: return (sun_cir (as, np, sp));
  1289. X    case MOON: return (moon_cir (as, np, sp));
  1290. X    case OBJX: lp = &objxlast; break;
  1291. X    default: lp = last + p; break;
  1292. X    }
  1293. X
  1294. X    /* if less than l_every days from last time for this planet
  1295. X     * just redo alt/az.
  1296. X     * always redo object x.
  1297. X     */
  1298. X    if (p != OBJX && same_cir (np, &lp->l_now)
  1299. X              && about_now (np, &lp->l_now, as*lp->l_dpas)) {
  1300. X        *sp = lp->l_sky;
  1301. X        new = 0;
  1302. X    } else {
  1303. X        double lpd0, psi0;    /* heliocentric ecliptic long and lat */
  1304. X        double rp0;        /* dist from sun */
  1305. X        double rho0;    /* dist from earth */
  1306. X        double lam, bet;    /* geocentric ecliptic long and lat */
  1307. X        double dia, mag;    /* angular diameter at 1 AU and magnitude */
  1308. X        double lsn, rsn;    /* true geoc lng of sun, dist from sn to earth*/
  1309. X        double el;    /* elongation */
  1310. X        double f;    /* phase from earth */
  1311. X
  1312. X        lp->l_now = *np;
  1313. X        sunpos (mjd, &lsn, &rsn);
  1314. X        if (p == OBJX)
  1315. X        objx_cir(mjd, &lpd0, &psi0, &rp0, &rho0, &lam, &bet,&sp->s_mag);
  1316. X        else {
  1317. X        double deps, dpsi;
  1318. X        double a;
  1319. X        plans(mjd, p, &lpd0, &psi0, &rp0, &rho0, &lam, &bet, &dia,&mag);
  1320. X        nutation (mjd, &deps, &dpsi);    /* correct for nutation */
  1321. X        lam += dpsi;
  1322. X        a = lsn-lam;            /* and 20.4" aberation */
  1323. X        lam -= degrad(20.4/3600)*cos(a)/cos(bet);
  1324. X        bet -= degrad(20.4/3600)*sin(a)*sin(bet);
  1325. X        }
  1326. X
  1327. X        ecl_eq (mjd, bet, lam, &lp->l_ra, &lp->l_dec);
  1328. X
  1329. X        sp->s_ra = lp->l_ra;
  1330. X        sp->s_dec = lp->l_dec;
  1331. X        if (epoch != EOD)
  1332. X        precess (mjd, epoch, &sp->s_ra, &sp->s_dec);
  1333. X        sp->s_edist = rho0;
  1334. X        sp->s_sdist = rp0;
  1335. X        elongation (lam, bet, lsn, &el);
  1336. X        el = raddeg(el);
  1337. X        sp->s_elong = el;
  1338. X        sp->s_size = (p != OBJX) ? dia/rho0 : 0.0;
  1339. X        f = 0.5*(1+cos(lam-lpd0));
  1340. X        sp->s_phase = f*100.0; /* percent */
  1341. X        /* objx_cir already returned the apparent magnitude */
  1342. X        if (p != OBJX)
  1343. X        sp->s_mag = mag + 5.0*log(rp0*rho0/sqrt(f))/log(10.0);
  1344. X        sp->s_hlong = lpd0;
  1345. X        sp->s_hlat = psi0;
  1346. X        new = 1;
  1347. X    }
  1348. X
  1349. X    /* alt, az; correct for parallax and refraction; use eod ra/dec */
  1350. X    now_lst (np, &lst);
  1351. X    ha = hrrad(lst) - lp->l_ra;
  1352. X    if (sp->s_edist > 0.0) {
  1353. X        ehp = (2.0*6378.0/146.0e6) / sp->s_edist;
  1354. X        ta_par (ha, lp->l_dec, lat, height, ehp, &ha, &dec);
  1355. X    } else
  1356. X        dec = lp->l_dec;
  1357. X    hadec_aa (lat, ha, dec, &alt, &az);
  1358. X    refract (pressure, temp, alt, &alt);
  1359. X    sp->s_alt = alt;
  1360. X    sp->s_az = az;
  1361. X    lp->l_sky = *sp;
  1362. X    return (new);
  1363. X}
  1364. X
  1365. X/* find local times when sun is 18 degrees below horizon.
  1366. X * return 0 if just returned same stuff as previous call, else 1 if new.
  1367. X */
  1368. Xtwilight_cir (np, dawn, dusk, status)
  1369. XNow *np;
  1370. Xdouble *dawn, *dusk;
  1371. Xint *status;
  1372. X{
  1373. X    static Now last_now;
  1374. X    static double last_dawn, last_dusk;
  1375. X    static int last_status;
  1376. X    int new;
  1377. X
  1378. X    if (same_cir (np, &last_now) && same_lday (np, &last_now)) {
  1379. X        *dawn = last_dawn;
  1380. X        *dusk = last_dusk;
  1381. X        *status = last_status;
  1382. X        new = 0;
  1383. X    } else {
  1384. X        double x;
  1385. X        (void) riset_cir (SUN,np,TWILIGHT,dawn,dusk,&x,&x,&x,&x,status);
  1386. X        last_dawn = *dawn;
  1387. X        last_dusk = *dusk;
  1388. X        last_status = *status;
  1389. X        last_now = *np;
  1390. X        new = 1;
  1391. X    }
  1392. X    return (new);
  1393. X}
  1394. X
  1395. X/* find sun's circumstances now.
  1396. X * as is the desired accuracy, in arc seconds; use 0.0 for best possible.
  1397. X * return 0 if only alt/az changes, else 1 if all other stuff updated too.
  1398. X */
  1399. Xsun_cir (as, np, sp)
  1400. Xdouble as;
  1401. XNow *np;
  1402. XSky *sp;
  1403. X{
  1404. X    static Sky last_sky;
  1405. X    static Now last_now;
  1406. X    static double last_ra, last_dec;    /* unprecessed ra/dec */
  1407. X    double lst, alt, az;
  1408. X    double ehp, ha, dec;    /* ehp: angular dia of earth from body */
  1409. X    int new;
  1410. X
  1411. X    if (same_cir (np, &last_now) && about_now (np, &last_now, as*.00028)) {
  1412. X        *sp = last_sky;
  1413. X        new = 0;
  1414. X    } else {
  1415. X        double lsn, rsn;
  1416. X        double deps, dpsi;
  1417. X
  1418. X        last_now = *np;
  1419. X        sunpos (mjd, &lsn, &rsn);        /* sun's true ecliptic long
  1420. X                         * and dist
  1421. X                         */
  1422. X        nutation (mjd, &deps, &dpsi);    /* correct for nutation */
  1423. X        lsn += dpsi;
  1424. X        lsn -= degrad(20.4/3600);        /* and light travel time */
  1425. X
  1426. X        sp->s_edist = rsn;
  1427. X        sp->s_sdist = 0.0;
  1428. X        sp->s_elong = 0.0;
  1429. X        sp->s_size = raddeg(4.65242e-3/rsn)*3600*2;
  1430. X        sp->s_mag = -26.8;
  1431. X        sp->s_hlong = lsn-PI;    /* geo- to helio- centric */
  1432. X        range (&sp->s_hlong, 2*PI);
  1433. X        sp->s_hlat = 0.0;
  1434. X
  1435. X        ecl_eq (mjd, 0.0, lsn, &last_ra, &last_dec);
  1436. X        sp->s_ra = last_ra;
  1437. X        sp->s_dec = last_dec;
  1438. X        if (epoch != EOD)
  1439. X        precess (mjd, epoch, &sp->s_ra, &sp->s_dec);
  1440. X        new = 1;
  1441. X    }
  1442. X
  1443. X    now_lst (np, &lst);
  1444. X    ha = hrrad(lst) - last_ra;
  1445. X    ehp = (2.0 * 6378.0 / 146.0e6) / sp->s_edist;
  1446. X    ta_par (ha, last_dec, lat, height, ehp, &ha, &dec);
  1447. X    hadec_aa (lat, ha, dec, &alt, &az);
  1448. X    refract (pressure, temp, alt, &alt);
  1449. X    sp->s_alt = alt;
  1450. X    sp->s_az = az;
  1451. X    last_sky = *sp;
  1452. X    return (new);
  1453. X}
  1454. X
  1455. X/* find moon's circumstances now.
  1456. X * as is the desired accuracy, in arc seconds; use 0.0 for best possible.
  1457. X * return 0 if only alt/az changes, else 1 if all other stuff updated too.
  1458. X */
  1459. Xmoon_cir (as, np, sp)
  1460. Xdouble as;
  1461. XNow *np;
  1462. XSky *sp;
  1463. X{
  1464. X    static Sky last_sky;
  1465. X    static Now last_now;
  1466. X    static double ehp;
  1467. X    static double last_ra, last_dec;    /* unprecessed */
  1468. X    double lst, alt, az;
  1469. X    double ha, dec;
  1470. X    int new;
  1471. X
  1472. X    if (same_cir (np, &last_now) && about_now (np, &last_now, as*.000021)) {
  1473. X        *sp = last_sky;
  1474. X        new = 0;
  1475. X    } else {
  1476. X        double lam, bet;
  1477. X        double deps, dpsi;
  1478. X        double lsn, rsn;    /* sun long in rads, earth-sun dist in au */
  1479. X        double edistau;    /* earth-moon dist, in au */
  1480. X        double el;        /* elongation, rads east */
  1481. X
  1482. X        last_now = *np;
  1483. X        moon (mjd, &lam, &bet, &ehp);    /* moon's true ecliptic loc */
  1484. X        nutation (mjd, &deps, &dpsi);    /* correct for nutation */
  1485. X        lam += dpsi;
  1486. X        range (&lam, 2*PI);
  1487. X
  1488. X        sp->s_edist = 6378.14/sin(ehp);    /* earth-moon dist, want km */
  1489. X        sp->s_size = 3600*31.22512*sin(ehp);/* moon angular dia, seconds */
  1490. X
  1491. X        ecl_eq (mjd, bet, lam, &last_ra, &last_dec);
  1492. X        sp->s_ra = last_ra;
  1493. X        sp->s_dec = last_dec;
  1494. X        if (epoch != EOD)
  1495. X        precess (mjd, epoch, &sp->s_ra, &sp->s_dec);
  1496. X
  1497. X        sunpos (mjd, &lsn, &rsn);
  1498. X        range (&lsn, 2*PI);
  1499. X        elongation (lam, bet, lsn, &el);
  1500. X
  1501. X        /* solve triangle of earth, sun, and elongation for moon-sun dist */
  1502. X        edistau = sp->s_edist/1.495979e8; /* km -> au */
  1503. X        sp->s_sdist =
  1504. X        sqrt (edistau*edistau + rsn*rsn - 2.0*edistau*rsn*cos(el));
  1505. X
  1506. X        /* TODO: improve mag; this is based on a flat moon model. */
  1507. X        sp->s_mag = -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el))));
  1508. X
  1509. X        sp->s_elong = raddeg(el);    /* want degrees */
  1510. X        sp->s_phase = fabs(el)/PI*100.0;    /* want non-negative % */
  1511. X        sp->s_hlong = sp->s_hlat = 0.0;
  1512. X        new = 1;
  1513. X    }
  1514. X
  1515. X    /* show topocentric alt/az by correcting ra/dec for parallax 
  1516. X     * as well as refraction.
  1517. X     */
  1518. X    now_lst (np, &lst);
  1519. X    ha = hrrad(lst) - last_ra;
  1520. X    ta_par (ha, last_dec, lat, height, ehp, &ha, &dec);
  1521. X    hadec_aa (lat, ha, dec, &alt, &az);
  1522. X    refract (pressure, temp, alt, &alt);
  1523. X    sp->s_alt = alt;
  1524. X    sp->s_az = az;
  1525. X    last_sky = *sp;
  1526. X    return (new);
  1527. X}
  1528. X
  1529. X/* given geocentric ecliptic longitude and latitude, lam and bet, of some object
  1530. X * and the longitude of the sun, lsn, find the elongation, el. this is the
  1531. X * actual angular separation of the object from the sun, not just the difference
  1532. X * in the longitude. the sign, however, IS set simply as a test on longitude
  1533. X * such that el will be >0 for an evening object <0 for a morning object.
  1534. X * to understand the test for el sign, draw a graph with lam going from 0-2*PI
  1535. X *   down the vertical axis, lsn going from 0-2*PI across the hor axis. then
  1536. X *   define the diagonal regions bounded by the lines lam=lsn+PI, lam=lsn and
  1537. X *   lam=lsn-PI. the "morning" regions are any values to the lower left of the
  1538. X *   first line and bounded within the second pair of lines.
  1539. X * all angles in radians.
  1540. X */
  1541. Xelongation (lam, bet, lsn, el)
  1542. Xdouble lam, bet, lsn;
  1543. Xdouble *el;
  1544. X{
  1545. X    *el = acos(cos(bet)*cos(lam-lsn));
  1546. X    if (lam>lsn+PI || lam>lsn-PI && lam<lsn) *el = - *el;
  1547. X}
  1548. X
  1549. X/* return whether the two Nows are for the same observing circumstances. */
  1550. Xsame_cir (n1, n2)
  1551. Xregister Now *n1, *n2;
  1552. X{
  1553. X    return (n1->n_lat == n2->n_lat
  1554. X        && n1->n_lng == n2->n_lng
  1555. X        && n1->n_temp == n2->n_temp
  1556. X        && n1->n_pressure == n2->n_pressure
  1557. X        && n1->n_height == n2->n_height
  1558. X        && n1->n_tz == n2->n_tz
  1559. X        && n1->n_epoch == n2->n_epoch);
  1560. X}
  1561. X
  1562. X/* return whether the two Nows are for the same LOCAL day */
  1563. Xsame_lday (n1, n2)
  1564. XNow *n1, *n2;
  1565. X{
  1566. X    return (mjd_day(n1->n_mjd - n1->n_tz/24.0) ==
  1567. X        mjd_day(n2->n_mjd - n2->n_tz/24.0)); 
  1568. X}
  1569. X
  1570. X/* return whether the mjd of the two Nows are within dt */
  1571. Xstatic
  1572. Xabout_now (n1, n2, dt)
  1573. XNow *n1, *n2;
  1574. Xdouble dt;
  1575. X{
  1576. X    return (fabs (n1->n_mjd - n2->n_mjd) <= dt/2.0);
  1577. X}
  1578. X
  1579. Xnow_lst (np, lst)
  1580. XNow *np;
  1581. Xdouble *lst;
  1582. X{
  1583. X    utc_gst (mjd_day(mjd), mjd_hr(mjd), lst);
  1584. X    *lst += radhr(lng);
  1585. X    range (lst, 24.0);
  1586. X}
  1587. X
  1588. X/* round a time in days, *t, to the nearest second, IN PLACE. */
  1589. Xrnd_second (t)
  1590. Xdouble *t;
  1591. X{
  1592. X    *t = floor(*t*SPD+0.5)/SPD;
  1593. X}
  1594. X    
  1595. Xdouble
  1596. Xmjd_day(jd)
  1597. Xdouble jd;
  1598. X{
  1599. X    return (floor(jd-0.5)+0.5);
  1600. X}
  1601. X
  1602. Xdouble
  1603. Xmjd_hr(jd)
  1604. Xdouble jd;
  1605. X{
  1606. X    return ((jd-mjd_day(jd))*24.0);
  1607. X}
  1608. EOFxEOF
  1609. len=`wc -c < circum.c`
  1610. if expr $len != 10181 > /dev/null
  1611. then echo Length of circum.c is $len but it should be 10181.
  1612. fi
  1613. echo x comet.c
  1614. sed -e 's/^X//' << 'EOFxEOF' > comet.c
  1615. X#include <math.h>
  1616. X#include "astro.h"
  1617. X
  1618. X/* given a modified Julian date, mjd, and a set of heliocentric parabolic
  1619. X * orbital elements referred to the epoch of date (mjd):
  1620. X *   ep:   epoch of perihelion,
  1621. X *   inc:  inclination,
  1622. X *   ap:   argument of perihelion (equals the longitude of perihelion minus the
  1623. X *       longitude of ascending node)
  1624. X *   qp:   perihelion distance,
  1625. X *   om:   longitude of ascending node;
  1626. X * find:
  1627. X *   lpd:  heliocentric longitude, 
  1628. X *   psi:  heliocentric latitude,
  1629. X *   rp:   distance from the sun to the planet, 
  1630. X *   rho:  distance from the Earth to the planet,
  1631. X *   lam:  geocentric ecliptic longitude, 
  1632. X *   bet:  geocentric ecliptic latitude,
  1633. X *         none are corrected for light time, ie, they are the true values for
  1634. X *       the given instant.
  1635. X *
  1636. X * all angles are in radians, all distances in AU.
  1637. X * mutual perturbation corrections with other solar system objects are not
  1638. X * applied. corrections for nutation and abberation must be made by the caller.
  1639. X * The RA and DEC calculated from the fully-corrected ecliptic coordinates are
  1640. X * then the apparent geocentric coordinates. Further corrections can be made,
  1641. X * if required, for atmospheric refraction and geocentric parallax.
  1642. X */
  1643. Xcomet (mjd, ep, inc, ap, qp, om, lpd, psi, rp, rho, lam, bet)
  1644. Xdouble mjd;
  1645. Xdouble ep, inc, ap, qp, om;
  1646. Xdouble *lpd, *psi, *rp, *rho, *lam, *bet;
  1647. X{
  1648. X    double w, s, s2;
  1649. X    double l, sl, cl, y;
  1650. X    double spsi, cpsi;
  1651. X    double rd, lsn, rsn;
  1652. X    double lg, re, ll;
  1653. X    double cll, sll;
  1654. X    double nu;
  1655. X
  1656. X#define    ERRLMT    0.0001
  1657. X        w = ((mjd-ep)*3.649116e-02)/(qp*sqrt(qp));
  1658. X        s = w/3;
  1659. X    while (1) {
  1660. X        double d;
  1661. X        s2 = s*s;
  1662. X        d = (s2+3)*s-w;
  1663. X        if (fabs(d) <= ERRLMT)
  1664. X        break;
  1665. X        s = ((2*s*s2)+w)/(3*(s2+1));
  1666. X    }
  1667. X
  1668. X        nu = 2*atan(s);
  1669. X    *rp = qp*(1+s2);
  1670. X    l = nu+ap;
  1671. X        sl = sin(l);
  1672. X    cl = cos(l);
  1673. X    spsi = sl*sin(inc);
  1674. X        *psi = asin(spsi);
  1675. X    y = sl*cos(inc);
  1676. X        *lpd = atan(y/cl)+om;
  1677. X    cpsi = cos(*psi);
  1678. X        if (cl<0) *lpd += PI;
  1679. X    range (lpd, 2*PI);
  1680. X        rd = *rp * cpsi;
  1681. X    sunpos (mjd, &lsn, &rsn);
  1682. X    lg = lsn+PI;
  1683. X        re = rsn;
  1684. X    ll = *lpd - lg;
  1685. X        cll = cos(ll);
  1686. X    sll = sin(ll);
  1687. X        *rho = sqrt((re * re)+(*rp * *rp)-(2*re*rd*cll));
  1688. X        if (rd<re) 
  1689. X            *lam = atan((-1*rd*sll)/(re-(rd*cll)))+lg+PI;
  1690. X    else
  1691. X        *lam = atan((re*sll)/(rd-(re*cll)))+*lpd;
  1692. X    range (lam, 2*PI);
  1693. X        *bet = atan((rd*spsi*sin(*lam-*lpd))/(cpsi*re*sll));
  1694. X}
  1695. EOFxEOF
  1696. len=`wc -c < comet.c`
  1697. if expr $len != 2390 > /dev/null
  1698. then echo Length of comet.c is $len but it should be 2390.
  1699. fi
  1700.  
  1701.